home *** CD-ROM | disk | FTP | other *** search
/ ADA Programming Guide / ADA Programming Guide.iso / ada_gnu / include / sys / farptr.h < prev    next >
C/C++ Source or Header  |  1996-01-30  |  6KB  |  217 lines

  1. /* Copyright (c) 1994 DJ Delorie.  Donated to the public domain.
  2.  
  3.    THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  4.    IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  5.    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  6.  
  7. ╔═══════════════════════════════════════════════════════════════════════╗
  8. ║        Far Pointer Simulation Functions            ║
  9. ╚═══════════════════════════════════════════════════════════════════════╝
  10.  
  11. This file attempts to make up for the lack of a "far" keyword in GCC. 
  12. Although it doesn't provide access to far call APIs (like Windows), it
  13. does allow you to do far pointer data access without the overhead of
  14. movedata() or dosmemget/dosmemput().
  15.  
  16. You should *always* include this file when using these functions and
  17. compile with optimization enabled.  They don't exist as normal functions
  18. in any library, and they compile down to only a few opcodes when used
  19. this way.  They are almost as fast as native pointer operations, and
  20. about as fast as far pointers can get. 
  21.  
  22. If you don't use optimization, this file becomes prototypes for
  23. farptr.c, which generates real functions for these when not optimizing. 
  24. When optimizing, farptr.c compiles to nothing. 
  25.  
  26. There are two types of functions here - standalone and invariant.  The
  27. standalone functions take a selector and offset.  These are used when
  28. you need only a few accesses, time isn't critical, or you don't know
  29. what's in the %fs register.  The invariant ones don't take a selector,
  30. they only take an offset.  These are used inside loops and in
  31. time-critical accesses where the selector doesn't change.  To specify
  32. the selector, use the farsetsel() function.  That selector is used for
  33. all farns*() functions until changed. 
  34.  
  35. The farpoke* and farpeek* take selectors.
  36.  
  37. The farnspoke* and farnspeek* don't (note the `ns' for `no selector').
  38.  
  39. Warning: These routines all use the %fs register for their accesses. 
  40. GCC normally uses only %ds and %es, and libc functions (movedata,
  41. dosmemget, dosmemput) use %gs.  Still, you should be careful about
  42. assumptions concerning whether or not the value you put in %fs will be
  43. preserved across calls to other functions.  If you guess wrong, your
  44. program will crash.  Better safe than sorry. 
  45.  
  46. Note: There are two places where asm constraints are casted.  One
  47. (farpokeb) is because signed char won't fit in unsigned char's range
  48. when arguments are constants, the other (farpeekb) gets compiled to (for
  49. example) %eax, but gas puts in opcodes for (for example) %al instead. 
  50. Both are workarounds for errors that gcc emits (but I don't know why). 
  51.  
  52. */
  53.  
  54. #ifndef _FAR_POINTER_H_
  55. #define _FAR_POINTER_H_
  56.  
  57. extern inline void
  58. _farpokeb(unsigned short selector,
  59.      unsigned long offset,
  60.      unsigned char value)
  61. {
  62.   asm("movw %0,%%fs"
  63.       :
  64.       : "r" (selector));
  65.   asm(".byte 0x64\n"
  66.       "    movb %0,(%1)"
  67.       :
  68.       : "r" ((unsigned char)value), "r" (offset));
  69. }
  70.  
  71. extern inline void
  72. _farpokew(unsigned short selector,
  73.      unsigned long offset,
  74.      unsigned short value)
  75. {
  76.   asm("movw %0,%%fs"
  77.       :
  78.       : "r" (selector));
  79.   asm(".byte 0x64\n"
  80.       "    movw %0,(%1)"
  81.       :
  82.       : "r" (value), "r" (offset));
  83. }
  84.  
  85. extern inline void
  86. _farpokel(unsigned short selector,
  87.      unsigned long offset,
  88.      unsigned long value)
  89. {
  90.   asm("movw %0,%%fs"
  91.       :
  92.       : "r" (selector));
  93.   asm(".byte 0x64\n"
  94.       "    movl %0,(%1)"
  95.       :
  96.       : "r" (value), "r" (offset));
  97. }
  98.  
  99. extern inline unsigned char
  100. _farpeekb(unsigned short selector,
  101.      unsigned long offset)
  102. {
  103.   unsigned char result;
  104.   asm("movw %0,%%fs"
  105.       :
  106.       : "r" (selector));
  107.   asm(".byte 0x64\n"
  108.       "    movb (%1),%0"
  109.       : "=r" ((int)result)
  110.       : "r" (offset));
  111.   return result;
  112. }
  113.  
  114. extern inline unsigned short
  115. _farpeekw(unsigned short selector,
  116.      unsigned long offset)
  117. {
  118.   unsigned short result;
  119.   asm("movw %0,%%fs"
  120.       :
  121.       : "r" (selector));
  122.   asm(".byte 0x64\n"
  123.       "    movw (%1),%0"
  124.       : "=r" (result)
  125.       : "r" (offset));
  126.   return result;
  127. }
  128.  
  129. extern inline unsigned long
  130. _farpeekl(unsigned short selector,
  131.      unsigned long offset)
  132. {
  133.   unsigned long result;
  134.   asm("movw %0,%%fs"
  135.       :
  136.       : "r" (selector));
  137.   asm(".byte 0x64\n"
  138.       "    movl (%1),%0"
  139.       : "=r" (result)
  140.       : "r" (offset));
  141.   return result;
  142. }
  143.  
  144. extern inline void
  145. _farsetsel(unsigned short selector)
  146. {
  147.   asm("movw %0,%%fs"
  148.       :
  149.       : "r" (selector));
  150. }
  151.  
  152. extern inline void
  153. _farnspokeb(unsigned long offset,
  154.      unsigned char value)
  155. {
  156.   asm(".byte 0x64\n"
  157.       "    movb %0,(%1)"
  158.       :
  159.       : "r" (value), "r" (offset));
  160. }
  161.  
  162. extern inline void
  163. _farnspokew(unsigned long offset,
  164.      unsigned short value)
  165. {
  166.   asm(".byte 0x64\n"
  167.       "    movw %0,(%1)"
  168.       :
  169.       : "r" (value), "r" (offset));
  170. }
  171.  
  172. extern inline void
  173. _farnspokel(unsigned long offset,
  174.      unsigned long value)
  175. {
  176.   asm(".byte 0x64\n"
  177.       "    movl %0,(%1)"
  178.       :
  179.       : "r" (value), "r" (offset));
  180. }
  181.  
  182. extern inline unsigned char
  183. _farnspeekb(unsigned long offset)
  184. {
  185.   unsigned char result;
  186.   asm(".byte 0x64\n"
  187.       "    movb (%1),%0"
  188.       : "=r" (result)
  189.       : "r" (offset));
  190.   return result;
  191. }
  192.  
  193. extern inline unsigned short
  194. _farnspeekw(unsigned long offset)
  195. {
  196.   unsigned short result;
  197.   asm(".byte 0x64\n"
  198.       "    movw (%1),%0"
  199.       : "=r" (result)
  200.       : "r" (offset));
  201.   return result;
  202. }
  203.  
  204. extern inline unsigned long
  205. _farnspeekl(unsigned long offset)
  206. {
  207.   unsigned long result;
  208.   asm(".byte 0x64\n"
  209.       "    movl (%1),%0"
  210.       : "=r" (result)
  211.       : "r" (offset));
  212.   return result;
  213. }
  214.  
  215. #endif /* _FAR_POINTER_H_ */
  216.  
  217.